


var EXPORTED_SYMBOLS = ["StrUtils", "MiscUtils"];

let [MiscUtils, StrUtils] = (function() {
    "use strict";
    const Cu = Components.utils;
    const Ci = Components.interfaces;
    const Cc = Components.classes;
    function require(url) {
        let scope = {};
        Cu.import(url, scope);
        return scope;
    }
    let {Prefs} = require("chrome://jsm/content/Preferences.js");
    let {Services} = require("resource://gre/modules/Services.jsm");

    return [  {
        compareFxVersion(version) {
            var info = Cc["@mozilla.org/xre/app-info;1"]
                .getService(Ci.nsIXULAppInfo);
            var vc = Cc["@mozilla.org/xpcom/version-comparator;1"]
                .getService(Ci.nsIVersionComparator);
            return vc.compare(info.version, version);
        },

        
        strings(name) {
            var bundle = Cc["@mozilla.org/intl/stringbundle;1"].
                getService(Ci.nsIStringBundleService).
                createBundle("chrome://imacros/locale/rec.properties");
            try {
                return bundle.GetStringFromName(name);
            } catch (e) {
                Components.utils.reportError("MiscUtils.strings() no string "+name);
            }
        },


        get browserWindow() {
            return Services.wm.getMostRecentWindow("navigator:browser");
        },

        
        
        __is_windows_int: undefined,

        isWindows() {
            if (typeof(this.__is_windows_int) == "undefined") {
                try {
                    this.__is_windows_int = Services.appinfo.OS == "WINNT";
                } catch (e) {
                    Components.utils.reportError(e);
                    this.__is_windows_int =
                        window.navigator.platform.search(/win/i) != -1;
                }
            }
            return this.__is_windows_int;
        },

        isMacOSX() {
            try {
                return Services.appinfo.OS == "Darwin";
            } catch (e) {
                Components.utils.reportError(e);
                return window.navigator.platform.search(/mac/i) != -1;
            }
        }
    },  {
        msg2con: function(code, errtext, extract, performance) {
            var s;
            if (code > 0)
                errtext = "Macro compeleted OK.";
            if (!extract) extract = "";
            if (!performance) performance = "";
            s = errtext+"[iim!E!iim]"+extract+"[iim!S!iim]"+performance;

            return s;
        },


        
        
        
        toInteger(num) {
            let s = num.toString();
            s = s.trim();
            if (!s.length)
                return Number.NaN;
            let n = parseInt(s);
            if (n.toString().length != s.length)
                return Number.NaN;
            return n;
        },

        
        encodeBase64(str) {
            let encoder = new TextEncoder("utf-8");
            let s = encoder.encode(str);
            return btoa(s);
        },

        
        decodeBase64(str) {
            let decoder = new TextDecoder("utf-8");
            let s = atob(str);
            return decoder.decode(s);
        },


        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

        unwrap(line) {
            const line_re = new RegExp("^\"((?:\n|.)*)\"$");
            var m = null;
            
            var handleSequence = function(s) {
                if (s == "\\\\") {
                    return "\u005C";
                } else if (s == "\\0") {
                    return "\u0000";
                } else if (s == "\\b") {
                    return "\u0008";
                } else if (s == "\\t") {
                    return "\u0009";
                } else if (s == "\\n") {
                    return "\u000A";
                } else if (s == "\\v") {
                    return "\u000B";
                } else if (s == "\\f") {
                    return "\u000C";
                } else if (s == "\\r") {
                    return "\u000D";
                } else if (s == "\\\"") {
                    return "\u0022";
                } else if (s == "\\\'") {
                    return "\u0027"
                } else {
                    
                    var replaceChar = function (match_str, char_code) {
                        return String.fromCharCode(parseInt("0x"+char_code));
                    };
                    if (/^\\x/.test(s))
                        return s.replace(/\\x([\da-fA-F]{2})/g, replaceChar);
                    else if (/^\\u/.test(s)) 
                        return s.replace(/\\u([\da-fA-F]{4})/g, replaceChar);
                }
            };

            var esc_re = new RegExp("\\\\(?:[0btnvfr\"\'\\\\]|x[\da-fA-F]{2}|u[\da-fA-F]{4})", "g");
            
            if (m = line.match(line_re)) {
                line = m[1];        
                
                line = line.replace(esc_re, handleSequence);
            } else {
                line = line.replace(/<br>/gi, '\n');
                line = line.replace(/<lf>/gi, '\r');
                line = line.replace(/<sp>/gi, ' ');
            }

            return line;
        },


        
        escapeLine(line) {
            var values_to_escape = {
                "\\u005C": "\\\\",
                "\\u0000": "\\0",
                "\\u0008": "\\b",
                "\\u0009": "\\t",
                "\\u000A": "\\n",
                "\\u000B": "\\v",
                "\\u000C": "\\f",
                "\\u000D": "\\r",
                "\\u0022": "\\\"",
                "\\u0027": "\\'"};
            
            for (var x in values_to_escape) {
                line = line.replace(new RegExp(x, "g"), values_to_escape[x]);
            }

            return line;
        },

        
        wrap(line) {
            const line_re = new RegExp("^\"((?:\n|.)*)\"$");

            var m = null;
            if (m = line.match(line_re)) { 
                line = this.escapeLine(m[1]);
                
                
                line = "\""+line+"\"";
            } else {
                line = line.replace(/\t/g, "<SP>");
                line = line.replace(/\n/g, "<BR>");
                line = line.replace(/\r/g, "<LF>");
                line = line.replace(/\s/g, "<SP>");
            }

            return line;
        },


        
        escapeREChars(str) {
            var chars = "^$.+?=!:|\\/()[]{}", res = "", i, j;
            for ( i = 0; i < str.length; i++) {
                for (j = 0; j < chars.length; j++) {
                    if (str[i] == chars[j]) {
                        res += "\\";
                        break;
                    }
                }
                res += str[i];
            }

            return res;
        },

        escapeTextContent(str) {
            
            
            str = str.trim();
            
            str = str.replace(/[\r\n]+/g, "");
            
            str = str.replace(/\s+/g, " ");

            return str;
        },

        
        formatDate(str, date) {
            let prepend = (str, len) => {
                str = str.toString(); 
                let x = this.toInteger(str);
                let y = this.toInteger(len);
                if (isNaN(x) || isNaN(y))
                    return;
                while (str.length < len)
                    str = '0'+str;
                return str;
            };
            let now = date ? date : new Date();
            str = str.replace(/yyyy/g, prepend(now.getFullYear(), 4));
            str = str.replace(/yy/g, now.getFullYear().toString().substr(-2));
            str = str.replace(/mm/g, prepend(now.getMonth()+1, 2));
            str = str.replace(/dd/g, prepend(now.getDate(), 2));
            str = str.replace(/hh/g, prepend(now.getHours(), 2));
            str = str.replace(/nn/g, prepend(now.getMinutes(), 2));
            str = str.replace(/ss/g, prepend(now.getSeconds(), 2));

            return str;
        }


    }];
})();
